/**
 * 基于 uni.request 封装的请求工具
 * 适配 ahooks-vue 的 useRequest
 */

// 请求默认配置
const DEFAULT_CONFIG = {
  baseURL: "https://mall.xiyibaomall.com/xyb", // API 地址（所有环境统一使用完整 URL）
  timeout: 20000, // 20秒超时
  header: {
    "Content-Type": "application/json",
    parentId: "81556ac364d84cc2b77817841dab21d2",
  },
};

/**
 * 获取 Token
 * 从本地存储中获取 token
 */
function getToken() {
  try {
    return uni.getStorageSync("token3") || "";
  } catch (e) {
    return "";
  }
}

/**
 * 设置 Token
 * @param {string} token - 用户令牌
 */
export function setToken(token) {
  try {
    uni.setStorageSync("token", token);
  } catch (e) {
    console.error("设置 token 失败:", e);
  }
}

/**
 * 清除 Token
 */
export function removeToken() {
  try {
    uni.removeStorageSync("token");
    uni.removeStorageSync("token1");
    uni.removeStorageSync("token2");
    uni.removeStorageSync("token3");
  } catch (e) {
    console.error("清除 token 失败:", e);
  }
}

/**
 * 获取用户 ID
 * 从本地存储中获取用户信息的 userId
 */
function getUserId() {
  try {
    const userInfo = uni.getStorageSync("userInfo");
    return userInfo?.userId || "";
  } catch (e) {
    return "";
  }
}

/**
 * 请求拦截器
 * @param {object} config - 请求配置
 * @returns {object} 处理后的配置
 */
function requestInterceptor(config) {
  // 动态添加 ac (token) 和 pid (userId)
  const token = getToken();
  const userId = getUserId();

  config.header = {
    ...config.header,
    ac: token || null,
    pid: userId || undefined,
  };

  return config;
}

/**
 * 响应拦截器
 * @param {object} response - 响应数据
 * @returns {Promise} 处理后的响应
 */
function responseInterceptor(response) {
  const { data, statusCode } = response;

  // HTTP 状态码处理
  if (statusCode >= 200 && statusCode < 300) {
    // 根据后端返回的数据结构调整
    // 后端返回格式: { code: 2000, data: {}, message: '' }
    if (data.code === 2000 || data.code === 0 || data.code === 200) {
      // 业务成功
      return Promise.resolve(data);
    } else if (data.code === 4000) {
      // 未登录或登录过期
      const errorMsg = data.message || "请先登录";
      uni.showToast({
        title: errorMsg,
        icon: "none",
        duration: 2000,
      });
      // 可选：跳转登录页
      // removeToken();
      // setTimeout(() => {
      //   uni.reLaunch({ url: '/pages/login/login' });
      // }, 2000);
      return Promise.reject(new Error(errorMsg));
    } else {
      // 其他业务错误
      const errorMsg = data.message || "请求失败";
      uni.showToast({
        title: errorMsg,
        icon: "none",
        duration: 2000,
      });
      return Promise.reject(new Error(errorMsg));
    }
  } else if (statusCode === 401) {
    // 未授权，跳转登录
    uni.showToast({
      title: "登录已过期，请重新登录",
      icon: "none",
      duration: 2000,
    });
    removeToken();
    setTimeout(() => {
      uni.reLaunch({
        url: "/pages/login/login",
      });
    }, 2000);
    return Promise.reject(new Error("未授权"));
  } else if (statusCode === 403) {
    // 无权限
    uni.showToast({
      title: "无权限访问",
      icon: "none",
      duration: 2000,
    });
    return Promise.reject(new Error("无权限"));
  } else if (statusCode === 404) {
    // 接口不存在
    uni.showToast({
      title: "请求的资源不存在",
      icon: "none",
      duration: 2000,
    });
    return Promise.reject(new Error("资源不存在"));
  } else if (statusCode >= 500) {
    // 服务器错误
    uni.showToast({
      title: "服务器错误，请稍后重试",
      icon: "none",
      duration: 2000,
    });
    return Promise.reject(new Error("服务器错误"));
  } else {
    // 其他错误
    const errorMsg = data.message || "请求失败";
    uni.showToast({
      title: errorMsg,
      icon: "none",
      duration: 2000,
    });
    return Promise.reject(new Error(errorMsg));
  }
}

/**
 * 错误处理
 * @param {object} error - 错误对象
 * @returns {Promise} reject
 */
function errorHandler(error) {
  console.error("请求错误:", error);

  let errorMsg = "网络请求失败";

  if (error.errMsg) {
    if (error.errMsg.includes("timeout")) {
      errorMsg = "请求超时，请稍后重试";
    } else if (error.errMsg.includes("fail")) {
      errorMsg = "网络连接失败，请检查网络";
    }
  }

  uni.showToast({
    title: errorMsg,
    icon: "none",
    duration: 2000,
  });

  return Promise.reject(error);
}

/**
 * 核心请求方法
 * @param {object} options - 请求配置
 * @returns {Promise} 返回 Promise
 */
function request(options) {
  // 合并配置
  const requestConfig = {
    ...DEFAULT_CONFIG,
    ...options,
    header: {
      ...DEFAULT_CONFIG.header,
      ...options.header,
    },
  };

  // 处理 URL
  if (!/^https?:\/\//.test(requestConfig.url)) {
    requestConfig.url = requestConfig.baseURL + requestConfig.url;
  }

  // 请求拦截
  const interceptedConfig = requestInterceptor(requestConfig);

  // 发起请求
  return new Promise((resolve, reject) => {
    uni.request({
      ...interceptedConfig,
      success: (res) => {
        responseInterceptor(res).then(resolve).catch(reject);
      },
      fail: (err) => {
        errorHandler(err).catch(reject);
      },
    });
  });
}

/**
 * GET 请求
 * @param {string} url - 请求地址
 * @param {object} params - 请求参数
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function get(url, params = {}, config = {}) {
  return request({
    url,
    method: "GET",
    data: params,
    ...config,
  });
}

/**
 * POST 请求
 * @param {string} url - 请求地址
 * @param {object} data - 请求数据
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function post(url, data = {}, config = {}) {
  return request({
    url,
    method: "POST",
    data,
    ...config,
  });
}

/**
 * PUT 请求
 * @param {string} url - 请求地址
 * @param {object} data - 请求数据
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function put(url, data = {}, config = {}) {
  return request({
    url,
    method: "PUT",
    data,
    ...config,
  });
}

/**
 * DELETE 请求
 * @param {string} url - 请求地址
 * @param {object} params - 请求参数
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function del(url, params = {}, config = {}) {
  return request({
    url,
    method: "DELETE",
    data: params,
    ...config,
  });
}

/**
 * 上传文件
 * @param {string} url - 上传地址
 * @param {string} filePath - 文件路径
 * @param {object} formData - 额外的表单数据
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function upload(url, filePath, formData = {}, config = {}) {
  // 处理 URL
  const uploadUrl = /^https?:\/\//.test(url)
    ? url
    : DEFAULT_CONFIG.baseURL + url;

  // 获取 token 和 userId
  const token = getToken();
  const userId = getUserId();
  const header = {
    ...DEFAULT_CONFIG.header,
    ...config.header,
    ac: token || null,
    pid: userId || undefined,
  };

  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: uploadUrl,
      filePath,
      name: "file",
      formData,
      header,
      success: (res) => {
        try {
          const data = JSON.parse(res.data);
          if (data.code === 2000 || data.code === 0 || data.code === 200) {
            resolve(data.data);
          } else {
            const errorMsg = data.message || "上传失败";
            uni.showToast({
              title: errorMsg,
              icon: "none",
              duration: 2000,
            });
            reject(new Error(errorMsg));
          }
        } catch (e) {
          reject(new Error("数据解析失败"));
        }
      },
      fail: (err) => {
        errorHandler(err).catch(reject);
      },
    });
  });
}

/**
 * 下载文件
 * @param {string} url - 下载地址
 * @param {object} config - 额外配置
 * @returns {Promise}
 */
export function download(url, config = {}) {
  // 处理 URL
  const downloadUrl = /^https?:\/\//.test(url)
    ? url
    : DEFAULT_CONFIG.baseURL + url;

  // 获取 token 和 userId
  const token = getToken();
  const userId = getUserId();
  const header = {
    ...DEFAULT_CONFIG.header,
    ...config.header,
    ac: token || null,
    pid: userId || undefined,
  };

  return new Promise((resolve, reject) => {
    uni.downloadFile({
      url: downloadUrl,
      header,
      success: (res) => {
        if (res.statusCode === 200) {
          resolve(res.tempFilePath);
        } else {
          reject(new Error("下载失败"));
        }
      },
      fail: (err) => {
        errorHandler(err).catch(reject);
      },
    });
  });
}

// 导出默认请求方法
export default request;
